import LGXCOM from '../../common/common'
import { LGXEnums } from "../../common/sysenum";


import { KeyGenerator } from '../../common/keygenerator.js'

import globalConst from "../../common/globalConst";
var global = globalConst.GlobalConst;
import { CoordTRFUtil } from "../../common/tools/coordtool";

import {CommonSvc} from "../../service/commonsvc.js";
import rotategraphsvc from "../../service/rotategraphsvc.js";
import UtilFuncs from "../../common/tools/utilfuncs";
var funcs = UtilFuncs.UtilFuncs;
import LXCOORD from '../../common/struct/coord.js'

import mapevent from "../../common/mapevent";
import { GlobalVar } from "../../common/globalvar";

import fillModule from '../../common/struct/fillinfo';

import { ExplodeSvc } from './explodesvc';
import arrowManager from '../../graph/paintutil/arrowManager';

var DrawCmdType = {};
DrawCmdType.line = 'l';
DrawCmdType.circle = 'c';
DrawCmdType.rect = 'r';
DrawCmdType.arc = 'a';
DrawCmdType.ellipse = 'ellipse';
DrawCmdType.ellipseArc = 'ellipseArc';

class EditSvc {
    constructor(dataManger, opsvc) {
        this.dataManger = dataManger;
        this.startRot = false;
        this.rotateCnt = null;
    }

    delete() {
        var list = this.dataManger.getSelGraphs();
        if (list.length > 0) {
            this.beginTransaction(list);
            console.log("delete ********************");
            console.log(list);
            var mulselrect = this.dataManger.getMulSelRectGraph();
            if (mulselrect) {
                list.push(mulselrect);
                this.dataManger.setMulSelRectGraph(null);
            }
            this.deleteGraphs(list);
            this.endTransaction(list);
        }
    }

    deleteGraphs(list) {
        let finalList = [];
        list.forEach((pGraph) => {
            let childList = pGraph.getAllChild();
            childList.forEach((p) => {
                if (finalList.indexOf(p) == -1) {
                    finalList.push(p);
                }
            });
        });

        for (let i = 0; i < finalList.length; i++) {
            let pGraph = finalList[i];
            if (pGraph.m_graphType == LGXEnums.LGXGraphType.TextGraph_type && pGraph.getParentGraph()) {
                continue;
            }
            pGraph.setUseful(0);
        }
    }

    finishDrawMultiPosGraph() {
        let evt = null;
        var pGraph = this.dataManger.getCurentGraph();
        if (pGraph && pGraph.getStart() == 1 && pGraph.getFinish() == 0) {
            pGraph.setFinish(1);
            let pt = { x: 0, y: 0 };
            let auxDataMng = this.dataManger.getAuxDataManager();
            auxDataMng.setVerticalLine(pt, pt, pt, pt, 0);
            auxDataMng.setParallelLine(pt, pt, pt, pt, 0);
            auxDataMng.setInterLine(pt, pt, pt, pt, 0);
            var list = new Array();
            this.dataManger.m_pOperStepService.record(0, list);

            evt = new mapevent.MapEvent;
            evt.finishNow = true;
            evt.gid = pGraph.m_gid;
            evt.uuid = pGraph.m_rid;
            evt.drawTool = pGraph.getType();
            evt.eventKind = LGXEnums.LGXEventKind.FinishDraw;
            this.endTransaction([]);
        }
        return evt;
    }

    modifyGraphDataByStru(info, needEditEventFlag) {
        let gid = info.gid;
        var isNew = false;
        var pGraph = null;
        if (info.exSetNewFlag) {
            var toolKind = info.type;
            pGraph = this.dataManger.productGraph(toolKind);
            if (pGraph) {
                isNew = true;
                pGraph.m_gid = KeyGenerator.gid();
            }
        }
        else {
            pGraph = this.dataManger.findGraph(gid);
        }
        if (!pGraph && !info.exSetNewFlag) {
            return;
        }
        if (isNew) {
            if (info.type >> 16 == global.BaseUnitText) {
                info.gid = KeyGenerator.gid();
                let canvasScreenRect = this.dataManger.getCanvasScreenRect();
                var mapInfo = this.dataManger.getMapViewInfo();
                var x = info.x - canvasScreenRect.left;
                var y = info.y - canvasScreenRect.top;
                var pt = { x, y };
                var wpt = CoordTRFUtil.screen2world(pt, mapInfo);
                info.x = wpt.x;
                info.y = wpt.y;
                info.pos.x = wpt.x;
                info.pos.y = wpt.y;
                info.m_nUseful = 1;
                info.m_nNewAdd = 1;
                pGraph.setUseful(1);
                pGraph.setNewAdd(1);
                this.dataManger.addCurentNewGraph(pGraph);
            }

            var list = new Array();
            this.beginTransaction(list);
            pGraph.assignInfo(info, 1);
            this.endTransaction(list);
        }
        else {
            var list = new Array();
            list.push(pGraph);
            this.beginTransaction(list);
            pGraph.modifyAttribute(info, 1);
            this.endTransaction(list);
        }
    }

    modifyGraphStyle(cmd) {
        console.log("modifyGraphStyle*********************");
        let arr = this.getCurentSelGraphs();
        this.beginTransaction(arr);
        this.modifyGraphDisProp(arr, cmd);
        this.endTransaction(arr);
    }

    modifyGraphDisProp(arr, cmd) {
        var propname = cmd.propname;
        var propval = cmd.propval;
        for (let idx = 0; idx < arr.length; idx++) {
            let pGraph = arr[idx];
            if (propname == "fill"
                || propname == "GradientAngle"
                || propname == "fillColor") {
                this.modifyFillProp(pGraph, propname, propval);
            }
            else if (propname == "preDefGradient") {
                this.modifyFillByPreDef(pGraph, propval);
            }
            else if (propname == "linewidth"
                || propname == "linemode"
                || propname == "color"){
                this.modifyLineProp(pGraph, propname, propval);
            }
            else if (propname == "fontColor"
                || propname == "fontsize"
                || propname == "fontFamily"
                || propname == "textAlign"
                || propname == "bold"
                || propname == "italic"
                || propname == "underline"
                || propname == "strikeout") {
                this.modifyTextProp(pGraph, propname, propval);
            }
            else if (propname == "arrow") {
                this.modifyLineArrowStyle(pGraph, cmd);
            }
            else if (propname == "line_connect_style") {
                this.modifyLineConnectStyle(pGraph, propval);
            }
            else if (propname == "xlink") {
                pGraph.setLink(propval);
            }
            else if (propname == "cadLineMode") {
                this.modifyCADLineModeProp(pGraph, propval);
            }
            else if (propname == "gradient_stopPos") {
                this.modifyGradientFillProp(pGraph, propval);
            }
            pGraph.calScope(1);
        }
    }

    modifyTextProp(pGraph, propname, propval) {
        let textGraph = null;
        if (pGraph.m_graphType == LGXEnums.LGXGraphType.TextGraph_type) {
            textGraph = pGraph;
        }
        else {
            textGraph = pGraph.getLabel();
        }
        if (!textGraph) {
            return;
        }

        var fontInfo = textGraph.getFontInfo();
        if (!fontInfo) {
            return;
        }

        if (propname == "fontColor") {
            fontInfo.fontColor.setColorByValue(parseInt(propval));
        }
        else if (propname == "fontsize") {
            fontInfo.fontsize = parseInt(propval);
        }
        else if (propname == "fontFamily") {
            fontInfo.fontFamily = propval;
        }
        else if (propname == "textAlign") {
            this.modifyTextAlign(textGraph, propval);
            if (pGraph.m_graphType != LGXEnums.LGXGraphType.TextGraph_type) {
                textGraph.resetLabelRect();
            }
        }
        else if (propname == 'bold'){
            fontInfo.bold = propval;			// 粗体
        }
        else if (propname == 'italic'){
            fontInfo.italic = propval;			// 粗体
        }
        else if (propname == 'underline'){
            fontInfo.underline = propval;			// 粗体
        }
        else if (propname == 'strikeout'){
            fontInfo.fontStrikeout = propval;			// 粗体
        }

        GlobalVar.fontInfo.clone(fontInfo);
    }

    modifyLineProp(pGraph, propname, propval) {
        let lineInfo = null;
        try {
            lineInfo = pGraph.getLineDef();
        }
        catch (error) {
            lineInfo = null;
        }
        finally {
            if (lineInfo) {
                if (propname == "linewidth") {
                    lineInfo.lineWidth = parseInt(propval);
                }
                else if (propname == "linemode") {
                    lineInfo.setModeByDesc(propval);
                }
                else if (propname == "color") {
                    lineInfo.color.setColorByValue(parseInt(propval));
                }
                GlobalVar.lineInfo.clone(lineInfo);
            }
        }
    }

    modifyLineArrowStyle(pGraph, cmd) {
        if (pGraph.m_graphType == LGXEnums.LGXGraphType.LineGraph_type) {
            let endFlag = cmd.flag;//0--首端  1---末端
            let lineInfo = pGraph.getLineDef();
            if (lineInfo) {
                let arrowMng = new arrowManager.LGXArrowManager();
                let info = arrowMng.getArrowInfoByIndex(parseInt(cmd.propval));
                if (info) {
                    if (endFlag == 0) {
                        lineInfo.stArrowType = info.name;
                    }
                    else if (endFlag == 1) {
                        lineInfo.endArrowType = info.name;
                    }
                }
            }
        }
    }

    modifyLineConnectStyle(pGraph, propval) {
        if (pGraph.m_graphType == LGXEnums.LGXGraphType.LineGraph_type) {
            pGraph.setVisionType(propval);
        }
    }

    modifyFillProp(graph, propname, propval) {
        console.log("modify fill prop");
        if (!funcs.isBaseUnit(graph.getType())) {
            return;
        }
        var fillInfo = graph.getFillDef();
        if (!fillInfo) {
            return;
        }
        let fillmode = propval.fillMode;
        if (fillmode == "none") {
            fillInfo.fillStyle = 0;
        }
        else if (fillmode == "solid") {
            fillInfo.fillStyle = 1;
        }
        else if (fillmode == "lineGradient") {
            if (fillInfo.fillStyle != LGXEnums.LGXFillStyle.lineGradient_complex){
                fillInfo.gradientInfo = null;
            }
            fillInfo.fillStyle = LGXEnums.LGXFillStyle.lineGradient_complex;
            let stopArr = propval.stopArr;
            fillInfo.setStop(stopArr);
            fillInfo.dir = propval.dir;
        }
        else if (fillmode == "radialGradient") {
            fillInfo.fillStyle = LGXEnums.LGXFillStyle.radialGradient_complex;
            let stopArr = propval.stopArr;
            fillInfo.setStop(stopArr);
            fillInfo.dir = propval.dir;
        }
        else if (propname == "fillColor") {
            fillInfo.fillColor.setColorByValue(parseInt(propval));
        }
        else if (propname == "GradientAngle") {
            fillInfo.degree = parseInt(propval);
        }
        else if (propname == "gradient_stopPos") {
            fillInfo.setStopPos(propval.subProp, propval.val);
        }
        if (!fillInfo.gradientInfo ||( fillInfo.gradientInfo && !fillInfo.gradientInfo.userSetPosFlag)){
            fillInfo.setStopDefaultPos(graph);
        }
        
        GlobalVar.fillInfo.clone(fillInfo);
    }

    modifyTextAlign(pGraph, propval) {
        let pos = propval.indexOf('_');
        var hornVert = propval.substr(0, pos);
        var valLen = propval.length - pos - 1;
        var type = propval.substr(pos + 1, valLen);
        if (hornVert == "horn") {
            pGraph.m_hornAlign = type;
        }
        else if (hornVert == "vert") {
            pGraph.m_vertAlign = type;
        }
    }

    rotate(degree) {
        console.log("rotate----------------------");
        var arr = new Array();
        var mulselRectGraph = this.dataManger.getMulSelRectGraph();
        if (!mulselRectGraph) {
            var curentGraph = this.dataManger.getCurentGraph();
            if (curentGraph) {
                arr.push(curentGraph);
            }
        }
        else {
            var count = this.dataManger.getSelectCount();
            for (let i = 0; i < count; i++) {
                var p = this.dataManger.getGraphInSelectList(i);
                arr.push(p);
            }
            arr.push(mulselRectGraph);
        }

        for (let i = 0; i < arr.length; i++) {
            var p = arr[i];
            let childLst = null;
            let pSupContainer = p.getContainer();
            if (pSupContainer) {
                childLst = pSupContainer.getChildList();
            }
            else {
                childLst = p.getChildList();
            }

            if (childLst) {
                childLst.forEach((child) => {
                    if (arr.indexOf(child) == -1) {
                        arr.push(child);
                    }
                });
            }
        }

        if (arr.length > 0) {
            let rect = null;
            if (!mulselRectGraph) {
                rect = CommonSvc.calGraphsZone(arr);
            }
            else {
                rect = mulselRectGraph.getZone();
            }
            this.rotateCnt = rect.getCnt();
            if (arr.length == 1) {
                let graph = arr[0];
                this.rotateCnt = graph.getLocalOrigin();
            }
            rotategraphsvc.RotateGraphSvc.rotate(this.rotateCnt, degree, arr, this.dataManger.getMapScale());
        }
    }

    closeInDrawingPolyline() {
        console.log("closeInDrawingPolyline***************");
        let evt = null;
        var curentGraph = this.dataManger.getCurentGraph();
        if (curentGraph && curentGraph.m_graphType == LGXEnums.LGXGraphType.LineGraph_type
            && curentGraph.getStart() == 1 && curentGraph.getFinish() == 0) {
            curentGraph.setClose(true);
            curentGraph.setFinish(1);
            this.endTransaction(0, []);

            evt = new mapevent.MapEvent;
            evt.finishNow = true;
            evt.gid = curentGraph.m_gid;
            evt.uuid = curentGraph.m_rid;
            evt.drawTool = curentGraph.getType();
            evt.eventKind = LGXEnums.LGXEventKind.FinishDraw;
        }
        return evt;
    }

    combine() {
        var list = this.dataManger.getSelGraphs();
        if (list.length < 2) {
            return "invalid selects";
        }
        this.creatCombineGraph(list);
    }

    creatCombineGraph(list) {
        if (list.length < 1) {
            return;
        }
        this.beginTransaction([]);
        let toolKind = global.CompositeFrameType;
        toolKind = toolKind << 16;
        let combineFrameGraph = this.dataManger.productGraph(toolKind);
        if (combineFrameGraph) {
            this.assignCombineFrameInfo(list, combineFrameGraph);
            combineFrameGraph.setFinish(1);
            combineFrameGraph.setStart(1);
            combineFrameGraph.calScope(1);
        }
        this.endTransaction([]);
    }

    assignCombineFrameInfo(list, combineFrameGraph) {
        var rect = CommonSvc.calGraphsZone(list);
        var multiPos = new LXCOORD.MultiPos();
        multiPos.addPoint(rect.ltPt());
        multiPos.addPoint(rect.rtPt());
        multiPos.addPoint(rect.rbPt());
        multiPos.addPoint(rect.lbPt());
        combineFrameGraph.setPos(multiPos);

        for (let i = 0; i < list.length; i++) {
            let graph = list[i];
            combineFrameGraph.addChild(graph);
        }
    }

    modifyCoordDatas(cmd) {
        console.log("modifyCoordDatas");
        let graph = this.getGraph(0);
        if (graph) {
            graph.modifyCoord(cmd.propName, cmd.propVal, this.dataManger.getMapScale());
        }
    }

    //1,锁定,0--解锁
    lockGraph(gid, lockflag, lockKind) {
        let graph = this.getGraph(gid);
        if (graph) {
            this.beginTransaction([graph]);
            graph.setLock(lockflag);
            this.endTransaction([]);
        }
    }

    modifyDrawingGraphByCMD(graphType, cmd) {
        let rst = null;
        let graph = this.getGraph(0);
        let isNew = false;
        if (!graph || (graph && graph.getStart() == 1 && graph.getFinish() == 1)) {
            graph = this.createNewGraphByCMDType(graphType);
            isNew = true;
        }
        if (!graph) {
            return null;
        }
        if (isNew) {
            this.beginTransaction([]);
        }
        let preUnFinish = false;
        if (graph.getStart() == 1 && graph.getFinish() == 0) {
            rst = graph.modifyByCMD(isNew, cmd);
            preUnFinish = true;
        }
        if (preUnFinish && graph.getStart() == 1 && graph.getFinish() == 1) {
            this.dataManger.getAuxDataManager().hideAuxiliaryGraph();
            this.endTransaction([]);
        }

        return rst;
    }

    sendCMD2SubEditControler(subEditMode, cmd) {
        let rst = null;
        let subEditMng = this.dataManger.getSubEditMngByMode(subEditMode);
        if (subEditMng) {
            rst = subEditMng.act2CMD(this.dataManger, cmd);
        }
        return rst;
    }

    createNewGraphByCMDType(graphType) {
        let tool = 0;
        switch (graphType) {
            case DrawCmdType.line:
                tool = global.BaseUnitPolyline;
                break;

            case DrawCmdType.circle:
                tool = global.BaseUnitCircle;
                break;

            case DrawCmdType.rect:
                tool = global.BaseUnitRectangle;
                break;

            case DrawCmdType.arc:
                tool = global.BaseUnitArc;
                break;

            case DrawCmdType.ellipse:
                tool = global.BaseUnitEllipse;
                break;

            case DrawCmdType.ellipseArc:
                tool = global.BaseUnitEllipseArc;
                break;
        }
        let graph = null;
        if (tool != 0) {
            tool = tool << 16;
            graph = this.dataManger.productGraph(tool);
            if (graph) {
                graph.m_gid = KeyGenerator.gid();
                graph.setStart(1);
                graph.setNewAdd(1);
                this.dataManger.setCurentGraph(graph);
                this.dataManger.addCurentNewGraph(graph);
            }
        }
        return graph;
    }

    getGraph(gid) {
        let graph = null
        if (gid == 0) {
            graph = this.dataManger.getCurentGraph();
        }
        else {
            graph = this.dataManger.findGraph(gid);
        }
        return graph;
    }

    //{ id: 'gradienID1', type:"line",desc:"左到右",st:{x:0,y:0},end:{x:1,y:0},stopArr: [{portion:0,color:'#0000ff'},{portion:1,color:'#ff00ff'}] },
    modifyFillByPreDef(pGraph, preDefInfo) {
        let fillInfo = pGraph.getFillDef();
        if (!fillInfo) {
            return;
        }

        console.log("modifyFillByPreDef");
        let mtx = pGraph.getLocalMatrix();
        let localRect = pGraph.getLocalZone();
        let basePt = localRect.ltPt();
        let localXAxis = funcs.getVector(basePt, localRect.rtPt());
        let localYAxis = funcs.getVector(basePt, localRect.lbPt());
        let localWid = localRect.width();
        let localHgt = localRect.height();

        let stPt = preDefInfo.st;
        let stx = basePt.x + stPt.x * localWid;
        let sty = basePt.y - stPt.y * localHgt;

        let worldPt = mtx.MultT({ x: stx, y: sty, z: 0 });//求相对于控制图形局部坐标系的局部坐标  
        fillInfo.setStopPos('st', worldPt);

        let endPt = preDefInfo.end;
        let stopx = basePt.x + endPt.x * localWid;
        let stopy = basePt.y - endPt.y * localHgt;
        worldPt = mtx.MultT({ x: stopx, y: stopy, z: 0 });//求相对于控制图形局部坐标系的局部坐标  
        fillInfo.setStopPos('end', worldPt);

        let tempArr = [];
        let stopArr = preDefInfo.stopArr;
        let stopCount = stopArr.length;
        for (let n = 0; n < stopCount; n++) {
            let stopInfo = stopArr[n];
            let proprotion = stopInfo.portion;
            let colorVal = stopInfo.color;
            let colorObj = new LGXCOM.LGXColor();
            colorObj.setByHexString(colorVal);
            let t = { stop: parseFloat(proprotion), color: colorObj.toValue() };
            tempArr.push(t);
        }
        fillInfo.setStop(tempArr);
    }

    // "makeAsTitle":
    // "makeAsTitleZone":
    // "makeAsEdge":

    setSymbolUnitMark(item) {
        let graph = this.getGraph(0);
        if (!graph) {
            return;
        }
        if (item == "makeAsTitle" && graph.m_graphType == LGXEnums.LGXGraphType.TextGraph_type) {
            graph.setTitleFlag(true);
        }
        else if (item == "makeAsTitleZone" && graph.m_graphType == LGXEnums.LGXGraphType.RectGraph_type) {
            graph.setTitleZoneFlag(true);
        }
        else if (item == "makeAsEdge" && graph.m_graphType == LGXEnums.LGXGraphType.RectGraph_type) {
            graph.setSymbolEdgeFlag(true);
        }
        else if (item == "makeAsLeadwire" && graph.m_graphType == LGXEnums.LGXGraphType.LineGraph_type) {
            graph.setSymbolLeadwireFlag(true);
        }
    }

    modifySymbolUnitCtrlInfo(unitCtlInfo) {
        console.log("modifySymbolUnitCtrlInfo(unitCtlInfo)");
        let graph = this.getGraph(0);
        if (!graph) {
            return;
        }
        if (graph.m_graphType == LGXEnums.LGXGraphType.RectGraph_type
            || graph.m_graphType == LGXEnums.LGXGraphType.PolygonGraph_type) {
            graph.setSymbolUnitCtrlInfo(unitCtlInfo);
        }
    }

    beginTransaction(list) {
        this.dataManger.m_pOperStepService.record(1, list);
    }

    endTransaction(list) {
        this.dataManger.m_pOperStepService.record(0, list);
    }


    explode(gid) {
        let arr = this.getCurentSelGraphs();
        arr.forEach(graph => {
            if (graph) {
                ExplodeSvc.explode(graph, this.dataManger);
            }
        });
    }

    getCurentSelGraphs() {
        let arr = [];
        let curentGraph = this.dataManger.getCurentGraph();
        if (curentGraph) {
            arr.push(curentGraph);
        }

        let count = this.dataManger.getSelectCount();
        for (let i = 0; i < count; i++) {
            let p = this.dataManger.getGraphInSelectList(i);
            if (arr.indexOf(p) == -1){
                arr.push(p);
            }
        }
        return arr;
    }

    modifyCADLineModeProp(pGraph, propval) {
        let lineInfo = null;
        try {
            lineInfo = pGraph.getLineDef();
        }
        catch (error) {
            lineInfo = null;
        }
        finally {
            if (lineInfo) {
                let mode = LGXEnums.LGXLineMode.Solid;
                switch (propval) {
                    case 'none':
                        mode = LGXEnums.LGXLineMode.NoPen;
                        break;
                    case 'solid':
                        mode = LGXEnums.LGXLineMode.Solid;
                        break;
                    case 'dash_dot':
                        mode = LGXEnums.LGXLineMode.Dash_Dot;
                        break;
                    case 'dash_do_dash':
                        mode = LGXEnums.LGXLineMode.Dash_DashDotDot;
                        break;
                    case 'dash_dash':
                        mode = LGXEnums.LGXLineMode.Dash_Dash;
                        break;
                }
                lineInfo.linemode = mode;
            }
        }
    }

    modifyGradientFillProp(graph, propval) {
        console.log("modify modifyGradientFillProp ");
        if (!funcs.isBaseUnit(graph.getType())) {
            return;
        }
        var fillInfo = graph.getFillDef();
        if (graph.m_graphType == LGXEnums.LGXGraphType.Cylinder_type) {
            let selIndex = graph.getSelect();
            if (selIndex % 2 == 1) {
                fillInfo = graph.coverFillDef;
            }
        }
        else if (graph.m_graphType == LGXEnums.LGXGraphType.Cube_type) {
            let selIndex = graph.getSelect();
            if (selIndex % 2 == 0) {
                fillInfo = graph.coverFillDef;
            }
            else if (selIndex % 3 == 0) {
                fillInfo = graph.rightFillDef;
            }
        }
        if (fillInfo) {
            fillInfo.setStopPos(propval.subProp, propval.val);
        }
    }

}

export default { EditSvc }